import {IFsmManager} from "./IFsmManager";
import {FsmState} from "./FsmState";
import { Fsm } from "./Fsm";
import {IFsm} from "./IFsm";
import ccclass = cc._decorator.ccclass;
import GameFrameworkModule from "../Base/GameFrameworkModule";
import FsmBase from "./FsmBase";
@ccclass("FsmManager")
export default class FsmManager implements GameFrameworkModule,IFsmManager{
    private readonly _fsms:Map<string,FsmBase&IFsm<any>>;

    constructor() {
        this._fsms = new Map<string, FsmBase&IFsm<any>>();
    }

    Count(): number {
        return this._fsms.size;
    }

    CreateFsm<T>(owner, name: string, states: FsmState<T>[]): IFsm<T>|FsmBase {
        if(this.HasFsm(owner,name)){
            throw new Error("Already exist FSM '{0}'."+name);
        }
        let fsm:Fsm<T>&FsmBase = Fsm.Create(name, owner, states);
        this._fsms.set(name, fsm);
        return fsm;
    }

    DestroyFsm<T>( name: string,owner?: IFsm<T> | FsmBase | T): boolean {
        let fsm:Fsm<T> = this._fsms.get(name) as Fsm<T>;
        if(fsm == null){
            return false;
        }
        fsm.Shutdown();
        return this._fsms.delete(name);
    }

    GetAllFsms<T>(): IFsm<T>[]|FsmBase[] {
        let arr = [];
        this._fsms.forEach(value => {
            arr.push(value);
        })
        return arr;
    }

    GetFsm<T>( name: string,owner?) :IFsm<T>|FsmBase {
        return this._fsms.get(name) as IFsm<T>;
    }

    HasFsm<T>( name: string,owner?): boolean {
        return this._fsms.has(name);
    }

    get Priority(): number {
        return 990;
    }

    Shutdown(): void {
        this._fsms.forEach(value => {
            value.Shutdown();
        })
        this._fsms.clear();
    }

    Update(elapseSeconds: number, realElapseSeconds: number): void {
        this._fsms.forEach(value => {
            value.Update(elapseSeconds,realElapseSeconds);
        })

    }

    get baseName(): string {
        return "GameFrameworkModule";
    }



}